/**
 *  Copyright (C) 2006 zhangbo (freeeob@gmail.com)
 *
 *  This product is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 * 
 *  This product is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 *
 *  author:zhangbo
 *  Email:jsjava@gmail.com
 */

/**  The PoissonDistributionImpl class references to org.apache.commons.math.distribution.PoissonDistributionImpl */

function PoissonDistributionImpl(p){
	this.jsjava_class="org.apache.commons.math.distribution.PoissonDistributionImpl";	
	if (p <= 0) {
        throw new IllegalArgumentException(
                IllegalArgumentException.ERROR,"The Poisson mean must be positive");
    }
    this.mean = p;
}

/**
 * The probability distribution function P(X <= x) for a Poisson distribution.
 * @param x
 */
PoissonDistributionImpl.prototype.cumulativeProbability=function(x){
	if (x < 0) {
        return 0;
    }
    if (x == Integer.MAX_VALUE) {
        return 1;
    }
    var sx=new String(x);
	if(sx.indexOf(".")!=-1){
		x=Math.floor(x);
	}
    return Gamma.regularizedGammaQ2(x + 1, this.mean, 
            1E-12, Integer.MAX_VALUE);
};

/**
 * Access the domain value lower bound, based on p, used to bracket a CDF root.
 * @param p
 */
PoissonDistributionImpl.prototype.getDomainLowerBound=function(p){
	return 0;
};

/**
 * Access the domain value upper bound, based on p, used to bracket a CDF root.
 * @param p
 */
PoissonDistributionImpl.prototype.getDomainUpperBound=function(p){
	return Integer.MAX_VALUE;
};

/**
 * Get the Poisson mean for the distribution.
 */
PoissonDistributionImpl.prototype.getMean=function(){
	return this.mean;
};

/**
 * Calculates the Poisson distribution function using a normal approximation.
 * @param x
 */
PoissonDistributionImpl.prototype.normalApproximateProbability=function(x){
	var normal = DistributionFactoryImpl.newInstance()
            .createNormalDistribution(this.getMean(),
                    Math.sqrt(this.getMean()));

    return normal.cumulativeProbability(x + 0.5);
};

/**
 * The probability mass function P(X = x) for a Poisson distribution.
 * @param x
 */
PoissonDistributionImpl.prototype.probability=function(x){
	if (x < 0 || x == Integer.MAX_VALUE) {
        return 0;
    }
    return Math.pow(this.getMean(), x) / 
        MathUtils.factorialDouble(x) * Math.exp(-this.mean);
};

/**
 * Set the Poisson mean for the distribution.
 * @param p
 */
PoissonDistributionImpl.prototype.setMean=function(p){
	if (p <= 0) {
        throw new IllegalArgumentException(
                IllegalArgumentException.ERROR,"The Poisson mean must be positive");
    }
    this.mean = p;
};